use crate::board::Player;

use std::collections::HashMap;
use std::fs::File;

use ndarray::Array2;

/// 打印Q表函数
///
/// # 参数
/// - `filename`: 保存Q表的文件名
///
/// # 错误处理
/// 返回Result，包含可能的错误信息
#[allow(unused_variables)]
#[allow(unreachable_code)]
pub fn print_q_table(
    filename: &str,
    limit: Option<usize>,
) -> Result<(), Box<dyn std::error::Error>> {
    todo!();
    // 1. 读取文件内容
    let file = File::open(filename)?;

    // 2. 反序列化Q表
    let mut reader = std::io::BufReader::new(file);
    let q_table: HashMap<Array2<Option<Player>>, Array2<f64>> =
        // bincode::decode_from_std_read(&mut reader, bincode::config::standard())
        //     .map_err(std::io::Error::other)?;
    todo!();

    // 3. 处理每个棋盘状态和对应的Q值
    for (board_state, q_values) in q_table.iter().take(limit.unwrap_or(usize::MAX)) {
        // 打印棋盘状态
        print_board_state(board_state);

        // 打印Q值表
        print_q_values(q_values);

        println!("{}", "-".repeat(50)); // 分隔线
    }

    Ok(())
}

/// 格式化打印棋盘状态
///
/// # 参数
/// - `board`: 棋盘状态数组
pub fn print_board_state(board: &Array2<Option<Player>>) {
    let (rows, cols) = board.dim();

    println!("Board State ({}x{}):", rows, cols);

    // 打印列号
    print!("    ");
    for c in 0..cols {
        print!("{:^5}", c); // 列号居中
    }
    println!();

    // 打印棋盘
    for r in 0..rows {
        print!("{:>2} |", r); // 行号右对齐
        for c in 0..cols {
            let symbol = match board[(r, c)] {
                Some(Player::Black) => "●",
                Some(Player::White) => "○",
                None => "·",
            };
            print!("{:^5}", symbol); // 棋子符号居中
        }
        println!("|");
    }
}

/// 格式化打印Q值表（保留一位小数并确保对齐）
///
/// # 参数
/// - `q_values`: Q值数组
pub fn print_q_values(q_values: &Array2<f64>) {
    let (rows, cols) = q_values.dim();

    println!("\nQ-Values ({}x{}):", rows, cols);

    // 打印列号
    print!("    ");
    for c in 0..cols {
        print!("{:^8}", c); // 列号居中
    }
    println!();

    // 打印Q值
    for r in 0..rows {
        print!("{:>2} |", r); // 行号右对齐

        for c in 0..cols {
            // 格式化数值：保留1位小数，总宽度7个字符（包括小数点和符号）
            let formatted = format!("{:>7.1}", q_values[(r, c)]);
            print!("{:^8}", formatted); // 数值居中
        }
        println!("|");
    }
}

/// 单元测试
#[cfg(test)]
mod tests {
    use super::*;
    use ndarray::{array, Array2 as Array2Ori};
    use std::{
        collections::HashMap,
        f64::consts::{E, PI},
    };
    use tempfile::NamedTempFile;

    #[test]
    fn test_print_q_table() {
        // 创建测试数据
        let mut q_table: HashMap<Array2<Option<Player>>, Array2<f64>> = HashMap::new();

        // 创建棋盘状态1 (2x2)
        let board1 = array![[Some(Player::Black), None], [None, Some(Player::White)]];

        // 创建对应的Q值
        let q_values1 = array![[0.0, 1.234], [2.345, -0.567]];

        // 创建棋盘状态2 (3x1)
        let board2 = array![[Some(Player::White)], [None], [Some(Player::Black)]];

        // 创建对应的Q值
        let q_values2 = array![[PI], [E], [0.0]];

        q_table.insert(
            <Array2Ori<Option<Player>>>::from(board1),
            <Array2Ori<f64>>::from(q_values1),
        );
        q_table.insert(
            <Array2Ori<Option<Player>>>::from(board2),
            <Array2Ori<f64>>::from(q_values2),
        );

        // 保存到临时文件
        let file = NamedTempFile::new().unwrap();
        let filename = file.path().to_str().unwrap();

        // let serialized = bincode::encode_to_vec(&q_table, bincode::config::standard()).unwrap();
        // std::fs::write(filename, serialized).unwrap();

        // 打印Q表
        print_q_table(filename, None).unwrap();
    }
}
